﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DotNetImage.Util;

namespace DotNetImage.Imaging
{
    /// <summary>
    /// Represents one red, green, blue or transpart part of the color in one pixel.
    /// If picture is a grayscale one, then it can be 1 byte. It also 1 byte when image is a color one then
    /// it represents red, blue or green color or alpha. In case of 64 or 128 bit image it will be ushort and uint correspondingly.
    /// So, it is either 8, 16 or 32 bits unsigned number
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ColorChannel<T>
        where T : struct,
                IComparable,
                IComparable<T>,
                IConvertible,
                IEquatable<T>,
                IFormattable
    {
        public static uint MaxValue<T>()
        {
            int size = TypeHelper.SizeOf(typeof(T));
            switch (size)
            {
                case 1:
                    return byte.MaxValue;
                case 2:
                    return ushort.MaxValue;
                case 4: 
                    return uint.MaxValue;
                default:
                    throw new ArgumentOutOfRangeException(typeof(T).ToString());
            }
        }

        public static uint MinValue()
        {
            return 0;
        }

        public T Value { get; set; }

        /// <summary>
        /// Per color calculation of the max value. Searches my value from the provided set of pixels for blue, red, green and alpha(?) channels.
        /// </summary>
        /// <param name="pixels"></param>
        /// <returns></returns>
        public static ColorChannel<T> GetMax(byte threshold = 0, params ColorChannel<T>[] pixels)
        {
            ColorChannel<T> result = new ColorChannel<T>();
            uint intMaxValue = ColorChannel<T>.MinValue();
            T intValue;
            if (pixels == null || pixels.Length == 0) return result;
            for (int i = 0; i < pixels.Length; i++)
            {
                intValue = pixels[i].Value;
                if (intValue > intMaxValue) intMaxValue = intValue;
            }

            if (intMaxValueBlue > 0) result.Blue = (byte)intMaxValueBlue;
            return result;
        }


        private T CheckBorders<T>(T input)
        {
            
            if (input > T.MaxValue) return T.MaxValue;
            if (input < 0) return 0;
            return (T)input;
        }

    }
}
